package com.gmrz.uap.common.db;

import io.shardingjdbc.core.api.ShardingDataSourceFactory;
import io.shardingjdbc.core.api.config.ShardingRuleConfiguration;
import io.shardingjdbc.core.api.config.TableRuleConfiguration;
import io.shardingjdbc.core.api.config.strategy.StandardShardingStrategyConfiguration;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class DataSourceJndiShardingDatabaseOnlyImpl implements DataSourceShardingFactory {

    @Override
    public DataSource getInstance() throws SQLException {
        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
        shardingRuleConfig.getTableRuleConfigs().add(getAuthenticatorsTableRuleConfiguration());
        shardingRuleConfig.getTableRuleConfigs().add(getDevicesTableRuleConfiguration());
        shardingRuleConfig.setDefaultDataSourceName(DataSourceShardingConst.getConfigInfo(DataSourceShardingConst.DATASOURCE_SHARDING_DATABASE_JNDI_DEFAUT));
        shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration(DataSourceShardingConst.SHARDING_KEY, ModuloShardingDatabaseAlgorithm.class.getName()));
        return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, new HashMap<String, Object>(), new Properties());
    }


    private static TableRuleConfiguration getAuthenticatorsTableRuleConfiguration() {
        TableRuleConfiguration authenticatorsTableRuleConfig = new TableRuleConfiguration();
        authenticatorsTableRuleConfig.setLogicTable(DataSourceShardingConst.SHARDING_TABLE_AUTHENTICATORS);
        return authenticatorsTableRuleConfig;
    }

    private static TableRuleConfiguration getDevicesTableRuleConfiguration() {
        TableRuleConfiguration devicesTableRuleConfig = new TableRuleConfiguration();
        devicesTableRuleConfig.setLogicTable(DataSourceShardingConst.SHARDING_TABLE_DEVICES);
        return devicesTableRuleConfig;
    }

    private static Map<String, DataSource> createDataSourceMap() {
        String[] jndiList = DataSourceShardingConst.getJndiSharding(DataSourceShardingConst.DATASOURCE_SHARDING_DATABASE_JNDI_LIST);

        final Map<String, DataSource> result = new HashMap<String, DataSource>();
        for (String jndiName : jndiList) {
            result.put(jndiName, DataSourceShardingConst.getDataSourceForJndi(jndiName));
        }

        return result;
    }


}
